﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace BattleThis.Core
{
	/// <summary>
	/// Represent a shallow list of fields. Access fields with the position.
	/// </summary>
	public class FieldDictionary : IEnumerable<KeyValuePair<Position,Field>>
	{

		#region Variablen
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets the intern Dictionary wich is used.
		/// </summary>
		/// <value>
		/// The intern.
		/// </value>
		protected Dictionary<Position, Field> Intern { get; set; }

		/// <summary>
		/// Gets the <see cref="BattleThis.Core.Field"/> with the specified column and row.
		/// </summary>
		public Field this[ int column, int row ]
		{
			get
			{
				var key = this.Intern.Keys.Where( x => ( x.Column.Equals( column ) && 
												  x.Row.Equals( row ) ) ).Single();
				return this.Intern[ key ];
			}
		}

		/// <summary>
		/// Gets the <see cref="BattleThis.Core.Field"/> with the specified position.
		/// </summary>
		public Field this[ Position position ]
		{
			get
			{
				if( position == null )throw new ArgumentNullException( "position" );

				return this[ position.Column, position.Row ];
			}
		}

		/// <summary>
		/// Gets the columns.
		/// </summary>
		public IEnumerable<IEnumerable<Field>> Columns
		{
			get
			{
				var groupResult = this.Items.GroupBy( x => x.Position.Column );
				return ( from item in groupResult let row = item.OrderBy( x => x.Position.Row ) select row );
			}
		}

		/// <summary>
		/// Gets the items.
		/// </summary>
		public IEnumerable<Field> Items
		{
			get { return this.Intern.Values; }
		}

		#endregion

		#region Methoden

		/// <summary>
		/// Initializes a new instance of the <see cref="FieldDictionary"/> class.
		/// </summary>
		/// <param name="fieldCount">The field count.</param>
		public FieldDictionary( int fieldCount )
		{
			this.Intern = new Dictionary<Position, Field>( fieldCount );
		}

		/// <summary>
		/// Creates a inialized FieldDictionary with the row and columns from the size.
		/// </summary>
		/// <param name="size">The size that specified the rows and columns.</param>
		/// <returns></returns>
		public static FieldDictionary CreateInialized( MapSize size )
		{
			var	fields =new FieldDictionary( size.FieldCount );

			for( int c = 0; c < size.Columns; c++ )
			{
				for( int r = 0; r < size.Rows; r++ )
				{
					var position = new Position( c, r );
					var field = new Field( position );

					fields.Add( field );
				}
			}

			return fields;
		}

		/// <summary>
		/// Adds the specified field to the collection.
		/// </summary>
		/// <param name="field">The field.</param>
		public void Add( Field field )
		{
			if( field == null )throw new ArgumentNullException( "field" );

			this.Intern.Add( field.Position, field );
		}

		#region IEnumerable<KeyValuePair<Position,Field>> Member

		public IEnumerator<KeyValuePair<Position, Field>> GetEnumerator()
		{
			return this.Intern.GetEnumerator();
		}

		#endregion

		#region IEnumerable Member

		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
		{
			return this.Intern.GetEnumerator();
		}

		#endregion

		#endregion

	}
}